#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据处理器模块
负责处理接收到的通信数据，解析协议并创建样本对象
"""

import logging
import time
import uuid
from datetime import datetime
from typing import Dict, Any, Optional

logger = logging.getLogger(__name__)

class DataProcessor:
    """数据处理器"""
    
    def __init__(self):
        self.parsers = {}
        self.register_parsers()
    
    def register_parsers(self):
        """注册协议解析器"""
        # 注册自定义LIS协议解析器（TCP版本）
        try:
            from src.protocols.tcp.tcp_protocol import CustomLISParser as TCPCustomLISParser
            self.parsers['tcp_custom_lis'] = TCPCustomLISParser()
            logger.info("自定义LIS协议解析器（TCP）注册成功")
        except Exception as e:
            logger.warning(f"自定义LIS协议解析器（TCP）不可用: {e}")
        
        # 注册自定义LIS协议解析器（串口版本）
        try:
            from src.protocols.serial.serial_protocol import CustomLISParser as SerialCustomLISParser
            self.parsers['serial_custom_lis'] = SerialCustomLISParser()
            logger.info("自定义LIS协议解析器（串口）注册成功")
        except Exception as e:
            logger.warning(f"自定义LIS协议解析器（串口）不可用: {e}")
    
    def process_data(self, data: bytes) -> dict:
        """处理接收到的数据"""
        try:
            # 检测协议类型
            protocol_type = self.detect_protocol(data)
            
            if protocol_type in self.parsers:
                return self.parsers[protocol_type].parse_message(data)
            else:
                logger.warning(f"未知协议类型: {protocol_type}")
                return {}
        except Exception as e:
            logger.error(f"数据处理失败: {e}")
            return {}
    
    def detect_protocol(self, data: bytes) -> str:
        """检测协议类型"""
        # 改进的协议检测逻辑
        if b'<TRANSMIT>' in data:
            # 检查是否为串口协议（可以通过其他特征区分）
            # 这里暂时都使用custom_lis，后续可以根据具体特征区分
            return 'custom_lis'
        elif data.startswith(b'STX'):
            return 'custom_lis'
        elif data.startswith(b'MSH'):
            return 'hl7'
        else:
            return 'unknown'
    
    def create_sample_from_parsed_data(self, parsed_data: dict, raw_data: str = "", communication_type: str = "TCP") -> Optional['Sample']:
        """从解析的数据创建Sample对象"""
        try:
            from src.models.models import Sample, SampleInfo, Results, ImageInfo, ModeInfo
            
            # 生成唯一ID
            unique_id = str(uuid.uuid4())
            
            # 根据通信类型确定协议名称
            base_protocol = parsed_data.get('protocol', 'CUSTOM_LIS')
            if communication_type == "TCP":
                protocol = f"TCP_{base_protocol}"
            else:
                protocol = f"SERIAL_{base_protocol}"
            
            # 创建SampleInfo对象
            sample_info_data = parsed_data.get('sample_info', {})
            sample_info = SampleInfo(
                sample_id=sample_info_data.get('sample_id', ''),
                sample_number=sample_info_data.get('sample_no', '') or sample_info_data.get('sample_number', ''),
                patient_name=sample_info_data.get('patient_name', '未知患者'),
                patient_age=sample_info_data.get('patient_age', 0),
                patient_gender=sample_info_data.get('patient_gender', ''),
                datetime=sample_info_data.get('datetime', ''),
                sample_type=sample_info_data.get('sample_type', ''),
                sample_type_name=sample_info_data.get('sample_type_name', ''),
                sample_category=sample_info_data.get('sample_category', ''),
                report_id=sample_info_data.get('report_id', '') or sample_info_data.get('sample_id', '')
            )
            
            # 创建Results对象
            results_data = parsed_data.get('results', {})
            results = Results(
                # 保持原始精度，不进行数值转换
                HbA1a=str(results_data.get('HbA1a', '0.00')),
                HbA1b=str(results_data.get('HbA1b', '0.00')),
                HbF=str(results_data.get('HbF', '0.00')),
                LA1c=str(results_data.get('LA1c', '0.00')),
                HbA1c=str(results_data.get('HbA1c', '0.00')),
                HbA0=str(results_data.get('HbA0', '0.00')),
                eAG=str(results_data.get('eAG', '0.00')),
                A2=str(results_data.get('A2', '0.00')),
                HbE=str(results_data.get('HbE', '0.00')),
                HbD=str(results_data.get('HbD', '0.00')),
                HbS=str(results_data.get('HbS', '0.00')),
                HbC=str(results_data.get('HbC', '0.00')),
                p3=str(results_data.get('p3', '0.00')),
                v_win=str(results_data.get('v-win', '0.00')),
                TIME=results_data.get('TIME', []),
                AREA=results_data.get('AREA', []),
                TIME_DETAILS=results_data.get('TIME_DETAILS', {}),
                AREA_DETAILS=results_data.get('AREA_DETAILS', {}),
                other_results=results_data.get('other_results', {})
            )
            
            # 创建ImageInfo对象
            image_data = parsed_data.get('image', {})
            logger.debug(f"处理图片数据: {image_data}")
            
            # 处理图片数据，支持多种字段名
            hex_data = image_data.get('hex_data', '') or image_data.get('data', '')
            base64_data = image_data.get('base64_data', '')
            
            image = ImageInfo(
                filename=image_data.get('filename', ''),
                size=image_data.get('size', 0),
                path=image_data.get('path', ''),
                saved=image_data.get('saved', False),
                hex_data=hex_data,
                base64_data=base64_data,
                error=image_data.get('error', '')
            )
            
            # 创建ModeInfo对象
            mode_info_data = parsed_data.get('mode_info', {})
            mode_info = ModeInfo(
                mode_name=mode_info_data.get('name', ''),
                mode_description=mode_info_data.get('description', ''),
                test_count=mode_info_data.get('test_count', 0),
                test_items=mode_info_data.get('test_items', [])
            )
            
            # 处理接收时间
            receive_time = datetime.now()
            if sample_info.datetime:
                try:
                    # 尝试解析时间格式
                    time_formats = [
                        "%Y-%m-%d-%H-%M",  # 2025-07-31-14-19
                        "%Y-%m-%d %H:%M:%S",  # 2025-07-31 14:19:30
                        "%Y-%m-%d %H:%M",  # 2025-07-31 14:19
                        "%Y/%m/%d %H:%M:%S",  # 2025/07/31 14:19:30
                    ]
                    
                    for fmt in time_formats:
                        try:
                            receive_time = datetime.strptime(sample_info.datetime, fmt)
                            break
                        except ValueError:
                            continue
                except Exception as e:
                    logger.warning(f"时间解析失败: {sample_info.datetime}, 使用当前时间")
            
            # 创建Sample对象
            sample = Sample(
                id=unique_id,
                protocol=protocol,  # 使用根据通信类型确定的协议名称
                machine_model=parsed_data.get('machine_model', ''),
                machine_id=parsed_data.get('machine_id', ''),
                sample_info=sample_info,
                results=results,
                image=image,
                analysis_mode=parsed_data.get('analysis_mode', ''),
                mode_info=mode_info,
                raw=raw_data,
                receive_time=receive_time
            )
            
            logger.info(f"成功创建Sample对象: {sample.id}, 协议: {protocol}, 通信类型: {communication_type}")
            return sample
            
        except Exception as e:
            logger.error(f"创建Sample对象失败: {e}")
            import traceback
            logger.error(f"详细错误信息: {traceback.format_exc()}")
            raise
    
    def extract_sample_info(self, parsed_data: dict, communication_type: str = "TCP") -> dict:
        """提取样本信息 - 保持向后兼容"""
        try:
            # 根据通信类型确定协议名称
            base_protocol = parsed_data.get('protocol', 'CUSTOM_LIS')
            if communication_type == "TCP":
                protocol = f"TCP_{base_protocol}"
            else:
                protocol = f"SERIAL_{base_protocol}"
            
            # 基础信息提取
            sample_info = {
                'instrument_id': parsed_data.get('machine_id', ''),
                'instrument_model': parsed_data.get('machine_model', ''),
                'instrument_number': parsed_data.get('machine_id', ''),
                'protocol_type': protocol,  # 使用根据通信类型确定的协议名称
                'sample_number': '',
                'sample_id': '',
                'instrument_type': parsed_data.get('machine_model', ''),
                'analysis_time': '',
                'test_results': '',
                'test_image_path': '',
                'report_id': '',
                'patient_name': '未知患者',
                'patient_age': 0,
                'patient_gender': ''
            }
            
            # 提取样本信息
            sample_data = parsed_data.get('sample_info', {})
            if sample_data:
                sample_info['sample_number'] = sample_data.get('sample_no', '') or sample_data.get('sample_number', '')
                sample_info['sample_id'] = sample_data.get('sample_id', '') or sample_data.get('sample_no', '')
                sample_info['report_id'] = sample_data.get('sample_id', '') or sample_data.get('sample_no', '')
                
                # 处理分析时间
                datetime_str = sample_data.get('datetime', '')
                if datetime_str:
                    try:
                        # 尝试解析时间格式
                        # 支持多种时间格式
                        time_formats = [
                            "%Y-%m-%d-%H-%M",  # 2025-07-31-14-19
                            "%Y-%m-%d %H:%M:%S",  # 2025-07-31 14:19:30
                            "%Y-%m-%d %H:%M",  # 2025-07-31 14:19
                            "%Y/%m/%d %H:%M:%S",  # 2025/07/31 14:19:30
                        ]
                        
                        parsed_time = None
                        for fmt in time_formats:
                            try:
                                parsed_time = datetime.strptime(datetime_str, fmt)
                                break
                            except ValueError:
                                continue
                        
                        if parsed_time:
                            sample_info['analysis_time'] = parsed_time.strftime("%Y-%m-%d %H:%M:%S")
                        else:
                            sample_info['analysis_time'] = datetime_str
                    except Exception as e:
                        logger.warning(f"时间解析失败: {datetime_str}, 错误: {e}")
                        sample_info['analysis_time'] = datetime_str
            
            # 提取检测结果
            results_data = parsed_data.get('results', {})
            if results_data:
                # 格式化检测结果
                formatted_results = []
                
                # 处理基础检测项目
                basic_items = ['HbA1a', 'HbA1b', 'HbF', 'LA1c', 'HbA1c', 'HbA0', 'eAG']  # 修正字段名
                for item in basic_items:
                    if item in results_data:
                        value = results_data[item]
                        formatted_results.append(f"{item}: {value}")
                
                # 处理变异筛查项目
                variant_items = ['A2', 'HbE', 'HbD', 'HbS', 'HbC', 'p3', 'v-win']
                for item in variant_items:
                    if item in results_data:
                        value = results_data[item]
                        formatted_results.append(f"{item}: {value}")
                
                # 处理TIME数据
                if 'TIME_DETAILS' in results_data:
                    time_details = results_data['TIME_DETAILS']
                    formatted_results.append("出峰时间:")
                    for time_item, time_value in time_details.items():
                        formatted_results.append(f"  {time_item}: {time_value}秒")
                
                # 处理AREA数据
                if 'AREA_DETAILS' in results_data:
                    area_details = results_data['AREA_DETAILS']
                    formatted_results.append("面积数据:")
                    for area_item, area_value in area_details.items():
                        formatted_results.append(f"  {area_item}: {area_value}")
                
                # 处理分析模式信息
                mode_info = parsed_data.get('mode_info', {})
                if mode_info:
                    formatted_results.append(f"分析模式: {mode_info.get('name', '未知')}")
                    formatted_results.append(f"模式描述: {mode_info.get('description', '')}")
                
                sample_info['test_results'] = '\n'.join(formatted_results)
            
            # 提取图片信息
            image_data = parsed_data.get('image', {})
            if image_data:
                sample_info['test_image_path'] = image_data.get('path', '')
                
                # 如果图片保存成功，记录图片信息
                if image_data.get('saved', False):
                    sample_info['test_image_path'] = image_data.get('path', '')
                    logger.info(f"图片已保存: {sample_info['test_image_path']}")
                else:
                    logger.warning(f"图片保存失败: {image_data.get('error', '未知错误')}")
            
            # 生成样本编号（如果没有的话）
            if not sample_info['sample_number']:
                timestamp = int(time.time())
                sample_info['sample_number'] = f"SAMPLE_{timestamp}"
                sample_info['sample_id'] = f"SAMPLE_{timestamp}"
                sample_info['report_id'] = f"SAMPLE_{timestamp}"
            
            # 记录接收时间
            if not sample_info['analysis_time']:
                sample_info['analysis_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            
            logger.info(f"提取的样本信息: {sample_info}")
            return sample_info
            
        except Exception as e:
            logger.error(f"提取样本信息失败: {e}")
            import traceback
            logger.error(f"详细错误信息: {traceback.format_exc()}")
            
            # 返回基础信息
            return {
                'instrument_id': parsed_data.get('machine_id', ''),
                'instrument_model': parsed_data.get('machine_model', ''),
                'instrument_number': parsed_data.get('machine_id', ''),
                'protocol_type': parsed_data.get('protocol', 'CUSTOM_LIS'),
                'sample_number': f"ERROR_{int(time.time())}",
                'sample_id': f"ERROR_{int(time.time())}",
                'instrument_type': parsed_data.get('machine_model', ''),
                'analysis_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'test_results': f"数据解析错误: {str(e)}",
                'test_image_path': '',
                'report_id': f"ERROR_{int(time.time())}",
                'patient_name': '未知患者',
                'patient_age': 0,
                'patient_gender': ''
            }
